
#include<stdio.h>
#include<math.h>
#include<string.h>

//31、题目：请输入星期几的第一个字母来判断一下是星期几，
//如果第一个字母一样，则继续判断第二个字母。
int main31 ()
{
    char f, s;
    printf("请输入要查询的星期首字母：");
    f = getchar();
    getchar();
    if (f == 'm')
        printf("星期一\n");
    else if(f=='w')
        printf("星期三\n");
    else if (f == 'f')
        printf("星期五\n");
    else 
    {
        printf("请输入第二个字母：\n");
        s = getchar();
        if(f=='t'&&s=='u')
            printf("星期二\n");
        else if(f=='t'&&s=='h')
            printf("星期四\n");
        else if(f=='s'&&s=='a')
            printf("星期六\n");
        else
            printf("星期日\n");
    }
    return 0;
}
//32、删除一个字符串中的指定字母，如：字符串 "aca"，删除其中的 a 字母。
int main32()
{
    char str[]={};
    printf("请输入字符串：");
    fgets(str,100,stdin);
    char c;
    printf("请输入要删除的字符：");
    c = getchar();
    for (int i = 0; str[i] != '\0';i++)
        if(str[i]==c)
            for (int k = i ; str[k] != '\0';k++)
                str[k] = str[k + 1];
    printf("删除后的字符串为：");
    puts(str);
    return 0;
}
//33、判断一个数字是否为质数
int is_prime(int n)
{
    if(n==1)
        return 0;
    int flag = 1;
    for (int i = 2; i <= sqrt(n); i++)
        if(n%i==0)
            flag = 0;
    return flag;
}
int main33()
{
    int n;
    printf("请输入要查询的数字：");
    scanf("%d", &n);
    if(is_prime(n)==1)
        printf("%d是质数\n",n);
    else
        printf("%d不是质数\n",n);
    return 0;
}
//35、字符串反转，如将字符串 "www.runoob.com" 反转为 "moc.boonur.www"
int main35()
{
    char str[] = {};
    //gets(str);
    fgets(str,100,stdin);//fgets会读取换行，gets不会
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--)
        printf("%c", str[i]);
    printf("\n");
    return 0;
}
//36、求100之内的素数。
int main36()
{
    for (int i = 1; i <= 100;i++)
        if(is_prime(i)==1)
            printf("%d ", i);
    return 0;
}
//37、对10个数进行排序。(选择排序)
int main37()
{
    int arr[10] = {23, 2, 27, 98, 234, 1, 4, 90, 88, 34};
    for (int i = 0; i < 9;i++)
    {
        //用后九个数里的最小值和第一个数比较
        int min = arr[i + 1];
        int k, t;
        for (k = i + 1; k < 10; k++)
            if(arr[k]<min)
            {
                min = arr[k];
                t = k;
            }
        if(arr[t]<arr[i])
        {
            int temp = arr[t];
            arr[t] = arr[i];
            arr[i] = temp;
        }
    }
    for (int i = 0; i < 10;i++)
        printf("%d ", arr[i]);
    return 0;
}
//38、求一个3*3矩阵对角线元素之和
int main38()
{
    int arr[3][3], sum = 0;
    printf("请输入3*3矩阵:");
    for (int i = 0; i < 3;i++)
        for (int k = 0; k < 3;k++)
        {
            scanf("%d", &arr[i][k]);
            if(i==k)
                sum += arr[i][k];
        }
    printf("矩阵对角线元素之和是：%d\n", sum);
    return 0;
}
//39、有一个已经排好序的数组。现输入一个数，要求按原来的规律将它插入数组中。
int main39()
{
    int arr[11] = {1, 4, 6, 9, 13, 16, 19, 28, 40, 100};
    printf("原数组为：");
    for (int i = 0; i < 10; i++)
        printf("%d ", arr[i]);
    int insert;
    printf("\n请输入要插入的数:");
    scanf("%d", &insert);
    //找到要插入的位置
    if(arr[9]<= insert)
        arr[10] = insert;    
    else 
    for (int i = 0; i < 10 ; i++)
        if (arr[i] >= insert )
        {
            //后面的数据依次后移
            for (int k = 9; k >= i; k--)
                arr[k + 1] = arr[k];
    
            arr[i] = insert;
            break;
        }
    //打印
    printf("插入后数组为：");
    for (int i = 0; i < 11;i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
//40、将一个数组逆序输出。
//前边写过一个直接从后往前输出的，这里交换一下
#define N 10
int main40()
{
    int arr[N]={1, 4, 6, 9, 13, 16, 19, 28, 40, 100};
    printf("原始数组为: ");
    for (int i = 0; i < 10; i ++)
        printf("%d ", arr[i]);
    for (int i = 0; i < N / 2; i ++)
    {
        int t = arr[i];
        arr[i] = arr[N - 1 - i];
        arr[N - 1 - i] = t;
    }
    printf("\n逆序数组为: ");
    for (int i = 0; i < 10; i ++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
//42、学习使用auto定义变量的用法。
//参考代码//没看懂
int main42()
{
    int i,num;
    num=2;
    for(i=0; i<3; i++)
    {
        printf("num 变量为 %d \n",num);
        num++;
        {
            auto int num=1;
            printf("内置模块 num 变量为 %d \n",num);
            num++;
        }
    }
    return 0;
}
//45、学习使用register定义变量的方法。
//register变量不能做取地址运算符&操作。
//声明变量具有register储类型就要求编译器把变量存储在寄存器中，而不是像其他变量一样保留在内存中。
//指明变量的存储类型是register是一种请求，而不是命令。编译器可以选择把register型变量存储在内存中。
// regste存储类型最好用于需要频繁进行访问或更新的变量。
//例如，在for语句中的循环控制变量就比较适合声明为register。
int main45()
{
    register int i;
    int tmp=0;
    for(i=1; i<=100; i++)
        tmp+=i;
    printf("总和为 %d\n",tmp);
    return 0;
}
//47、宏#define命令练习2。
#define exchange(a,b) { int t;t=a;a=b;b=t;}//注意放在一行里
int main47()
{
    int x=10;
    int y=20;
    printf("x=%d; y=%d\n",x,y);
    exchange(x,y);
    printf("x=%d; y=%d\n",x,y);
    return 0;
}
//49、#if #ifdef和#ifndef的综合应用。
#define MAX
#define MAXIMUM(x,y)(x>y)?x:y
#define MINIMUM(x,y) (x>y)?y:x
int main49()
{
    int a=10,b=20;
#ifdef MAX
    printf("更大的数字是 %d\n",MAXIMUM(a,b));
#else
    printf("更小的数字是 %d\n",MINIMUM(a,b));
#endif
#ifndef MIN
    printf("更小的数字是 %d\n",MINIMUM(a,b));
#else
    printf("更大的数字是 %d\n",MAXIMUM(a,b));
#endif
#undef MAX
#ifdef MAX
    printf("更大的数字是 %d\n",MAXIMUM(a,b));
#else
    printf("更小的数字是 %d\n",MINIMUM(a,b));
#endif
#define MIN
#ifndef MIN
    printf("更小的数字是 %d\n",MINIMUM(a,b));
#else
    printf("更大的数字是 %d\n",MAXIMUM(a,b));
#endif
    return 0;
}

//#line 100 "13.7.C"
#include <stdio.h>
 
int main222(void) { 
      
   printf("1.The current line NO.:%d\n", __LINE__);
   printf("2.The current line NO.:%d\n", __LINE__);

   printf("3.The current file name is:%s\n", __FILE__);

   return 0;
}
//56、画图，学用circle画圆形。
//MAC好像整不了EasyX库,呸！
// #include <graphics.h> //VC6.0中是不能运行的，要在Turbo2.0/3.0中
// int main()
// {
//     int driver,mode,i;
//     float j=1,k=1;
//     driver=VGA;
//     mode=VGAHI;
//     initgraph(&driver,&mode,"");
//     setbkcolor(YELLOW);
//     for(i=0; i<=25; i++)
//     {
//         setcolor(8);
//         circle(310,250,k);
//         k=k+j;
//         j=j+0.3;
//     }
//     return 0;
// }

//61、打印出杨辉三角形（要求打印出10行）。
/*
                        1
                     1     1
                  1     2     1
               1     3     3     1
            1     4     6     4     1
         1     5     10    10    5     1
      1     6     15    20    15    6     1    

*/
#define N 10
//空格这个玩意儿，懒得整了
int main61()
{
    int arr[20] = {0};
    arr[0] = 1;
    for (int i = 0; i < N;i++)
    {
        for (int k = i; k > 0; k--)
            arr[k] += arr[k - 1];
        for (int j = 0; j <= i;j++)
            printf("%-4d", arr[j]);
        printf("\n");
    }
    return 0;
}
//66、输入3个数a,b,c，按大小顺序输出。
void swap(int* x,int* y)
{
    int t = *x;
    *x = *y;
    *y = t;
}
int main66()
{
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    if(a>b)
        swap(&a, &b);
    if (a > c)
        swap(&a, &c);
    if (b > c)
        swap(&b, &c);
    printf("%d %d %d\n", a, b, c);
    return 0;
}
//67、输入数组，最大的与第一个元素交换，最小的与最后一个元素交换，输出数组。
int main67()
{
    int arr[] = {23, 2, 27, 98, 234, 1, 4, 90, 88, 34};
    int len =sizeof(arr) / sizeof(arr[0]);
    //先打印一下
    for (int i = 0; i < len;i++)
        printf("%d ", arr[i]);
    printf("\n");
    int max = arr[0], min = arr[0], t1 = 0, t2 = 0;
    //找出最大值最小值以及下标
    for (int i = 0; i < len; i++)
    {
        if(arr[i]>max)
        {
            max = arr[i];
            t1 = i;
        }
        if(arr[i]<min)
        {
            min = arr[i];
            t2 = i;
        }
    }
    //交换
    swap(arr, arr + t1);
    swap(arr + len - 1, arr + t2);
    //输出
    for (int i = 0; i < len;i++)
        printf("%d ", arr[i]);
    printf("\n");

    return 0;
}
//68、有 n个整数，使其前面各数顺序向后移 m 个位置，最后m个数变成最前面的 m 个数。
//不就是数组右移...
int main68()
{
    int arr[20];
    int n, m;
    printf("请输入数组总个数和要移动的位数：");
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n;i++)
        scanf("%d", &arr[i]);
    m %= n;
    //直接打印法
    for (int i = 0; i < m;i++)
        printf("%d ", arr[i + n - m]);
    for (int i = 0; i < n - m;i++)
        printf("%d ", arr[i]);
    return 0;
}
//69、有n个人围成一圈，顺序排号。从第一个人开始报数（从1到3报数），
//凡报到3的人退出圈子，问最后留下的是原来第几号的那位。
//约瑟夫自杀环
//循环链表法
#include<stdlib.h>
typedef struct CList
{
    int data;
    struct CList *next;
} CL;
//开一个新节点，将i存进去
CL* CLByNode (int i)
{
    CL *node = (CL *)malloc(sizeof(CL));
    node->data = i;
    node->next = NULL;
    return node;
}
int main69_1()
{
    int n;
    printf("请输入总人数：");
    scanf("%d", &n);
    //创建一个不带头循环单链表
    CL *head, *tail;
    head = tail = CLByNode(1);
    //依次将数据加进去
    for (int i = 2; i <= n; i++)
    {
        CL *node = CLByNode(i);
        tail->next = node;
        tail = tail->next;
    }
    //首尾相连
    tail->next = head;
    //遍历
    CL *cur = head, *prev;
    int count = 1;
    //判断是否只剩一个节点
    while(cur!=cur->next)
    {
        //（记录一下前一个节点，方便删除）
        prev = cur;
        cur = cur->next;
        count++;
        if(count==3)
        {
            //删除节点
            prev->next = cur->next;
            free(cur);
            cur = prev->next;
            count = 1;
        }
    }
    printf("最终留下的是%d号位", cur->data);
    return 0;
}
//用递归，一行代码解决 NB！
//删掉一个就重新编号，删掉的下一个就为1
int ysf(int n,int m)
{
    // if(n==1)    return n;
    // return (ysf(n - 1, m) + m - 1) % n + 1;
    //先-1又+1是为了避免新编号+m正好等于n的情况
    //为了装B，搞到一行去
    return n == 1 ? n : (ysf(n - 1, m) + m - 1) % n + 1;
}
int main69_2()
{
    int n, m;
    printf("请输入总人数和要报到的数：");
    scanf("%d%d", &n, &m);
    printf("最终留下的是%d号位\n",ysf(n,m));
    return 0;
}
//70、写一个函数，求一个字符串的长度，在 main 函数中输入字符串，并输出其长度。
//模拟strlen吗
int my_strlen(char s[])
{
    int i = 0;
    for (; s[i] != '\0';i++)
        ;
    return i;
}
int main()
{
    char s[100];
    printf("请输入字符串：");
    scanf("%s", s);
    int len = my_strlen(s);
    printf("该字符串包含%d个字符\n",len);
}
